package gameengine;
import gameobjects.Actor;
import gameobjects.Ammo;
import gameobjects.Bullet;
import gameobjects.Chaser;
import gameobjects.Crate;
import gameobjects.EnemyEntity;
import gameobjects.Entity;
import gameobjects.Weapon;
import gameobjects.LMG;
import gameobjects.Pistol;
import gameobjects.PlayerEntity;
import gameobjects.RocketLauncher;
import gameobjects.Shotgun;
import gameobjects.Zombie;
import gameobjects.Swordsman;
import gameobjects.Soldier;
import gameobjects.Boss;

import java.util.ArrayList;


public class EntityMgr {

	private ArrayList<Entity> entityList;
	private ArrayList<EnemyEntity> enemyList;
	private ArrayList<Bullet> bulletList;
	private ArrayList<Crate> crateList;
	private ArrayList<Weapon> weaponList;
	private PlayerEntity playerEntity;
	private int lastHandle;
	
	
	EntityMgr(){
		entityList = new ArrayList<Entity>();
		enemyList = new ArrayList<EnemyEntity>();
		bulletList = new ArrayList<Bullet>();
		crateList = new ArrayList<Crate>();
		weaponList = new ArrayList<Weapon>();
		lastHandle = -1;
	}
	
	//Creates an entity with the given parameters and adds it to the entityList
	public Entity createEntity(String n, String s, int x, int y, int w, int h){
		lastHandle++;
		Entity ent = new Entity(lastHandle,n,s,x,y,w,h);
		entityList.add(ent);
		return ent;
	}

	//Returns the entityList
	public ArrayList<Entity> getEntityList(){
		return entityList;
	}
	
	//Creates a bullet according to the given actor then adds it to the entity list and bulletlist
	public Bullet createBullet(Actor actor, long launchTime){	
		if (actor instanceof Soldier){
			lastHandle++;
			Bullet mBullet = ((Soldier)actor).getBullet();
			Bullet bullet = new Bullet(mBullet, lastHandle,  actor.getX() + actor.getW()/2, actor.getY() + actor.getH()/2 + 5, launchTime);
			bullet.setDirection(actor.getDirection());
			if (bullet.getDirection() == "left" )
				bullet.setSpeed(-bullet.getSpeed());
			entityList.add(bullet);
			bulletList.add(bullet);
			return bullet;
		}
		else if (actor instanceof Boss){
			lastHandle++;
			Bullet mBullet = ((Boss)actor).getBullet();
			Bullet bullet = new Bullet(mBullet, lastHandle,  actor.getX() + actor.getW()/2, actor.getY() + actor.getH()/2 - 4, launchTime);
			bullet.setDirection(actor.getDirection());
			if (bullet.getDirection() == "left" )
				bullet.setSpeed(-bullet.getSpeed());
			entityList.add(bullet);
			bulletList.add(bullet);
			return bullet;
		}
		else if (actor instanceof PlayerEntity){
			lastHandle++;
			Bullet mBullet = ((PlayerEntity)actor).getBullet();
			Bullet bullet = new Bullet(mBullet, lastHandle,  actor.getX() + actor.getW()/2, actor.getY() + actor.getH()/2-17, launchTime);
			bullet.setDirection(actor.getDirection());
			if (bullet.getDirection() == "left" )
				bullet.setSpeed(-bullet.getSpeed());
			entityList.add(bullet);
			bulletList.add(bullet);
			return bullet;
		}
		else 
			return null;
	}
	
	//Returns the bulletList
	public ArrayList<Bullet> getBulletList(){
		return bulletList;
	}
	
	//Creates a pistol at given coordinates and adds it to the respective lists
	public Pistol createPistol(int x, int y){
		lastHandle++;
		Pistol z = new Pistol(lastHandle,x,y);
		entityList.add(z);
		weaponList.add(z);
		return z;
	}
	
	//Creates a chaser at given coordinates and adds it to the respective lists
	public Chaser createChaser(int x, int y){
		lastHandle++;
		Chaser z = new Chaser(lastHandle,x,y);
		entityList.add(z);
		weaponList.add(z);
		return z;
	}
	
	//Creates a rocket launcher at given coordinates and adds it to the respective lists
	public RocketLauncher createRocketLauncher(int x, int y){
		lastHandle++;
		RocketLauncher z = new RocketLauncher(lastHandle,x,y);
		entityList.add(z);
		weaponList.add(z);
		return z;
	}
	
	//Creates a light machine gun at given coordinates and adds it to the respective lists
	public LMG createLMG(int x, int y){
		lastHandle++;
		LMG z = new LMG(lastHandle,x,y);
		entityList.add(z);
		weaponList.add(z);
		return z;
	}

	//Creates a shotgun at given coordinates and adds it to the respective lists
	public Shotgun createShotgun(int x, int y){
		lastHandle++;
		Shotgun z = new Shotgun(lastHandle,x,y);
		entityList.add(z);
		weaponList.add(z);
		return z;
	}
	
	//Creates an ammo box at given coordinates and adds it to the respective lists
	public Ammo createAmmo(int x, int y){
		lastHandle++;
		Ammo z = new Ammo(lastHandle,x,y);
		entityList.add(z);
		weaponList.add(z);
		return z;
	}
	
	//Returns the weaponList
	public ArrayList<Weapon> getWeaponList() {
		return weaponList;
	}
	
	//Creates an crate at given coordinates and adds it to the respective lists
	public Crate createCrate(int x, int y)
	{
		lastHandle++;
		Crate z = new Crate(lastHandle,"crate","crate",x,y);
		entityList.add(z);
		crateList.add(z);
		return z;
	}
	
	//Returns the crateList
	public ArrayList<Crate> getCrateList(){
		return crateList;
	}
	
	//Creates a zombie at given coordinates and adds it to the respective lists
	public Zombie createZombie(int x, int y){
		lastHandle++;
		Zombie z = new Zombie(lastHandle,x,y);
		entityList.add(z);
		enemyList.add(z);
		return z;
	}
	
	//Creates a swordsman at given coordinates and adds it to the respective lists
	public Swordsman createSwordsman(int x, int y){
		lastHandle++;
		Swordsman z = new Swordsman(lastHandle,x,y);
		entityList.add(z);
		enemyList.add(z);
		return z;
	}
	
	//Creates a soldier at given coordinates and adds it to the respective lists
	public Soldier createSoldier(int x, int y){
		lastHandle++;
		Soldier z = new Soldier(lastHandle,x,y);
		entityList.add(z);
		enemyList.add(z);
		return z;
	}
	
	//Creates a boss at given coordinates and adds it to the respective lists
	public Boss createBoss(int x, int y){
		lastHandle++;
		Boss z = new Boss(lastHandle,x,y);
		entityList.add(z);
		enemyList.add(z);
		return z;
	}
	
	//Returns the enemyList
	public ArrayList<EnemyEntity> getEnemyList(){
		return enemyList;
	}
	
	//Returns the playerEntity
	//		if player entity does not exist, creates it before returning it.
	public PlayerEntity getPlayerEntity(){
		if (playerEntity == null){
			lastHandle++;
			playerEntity = new PlayerEntity(lastHandle);
			entityList.add(playerEntity);
		}
		return playerEntity;
	}
	
	//Destroy an entity with given handle and removes it from the respective lists
	public void destroyEntity(int handle){
		if (playerEntity.getHandle() == handle){
			playerEntity = null;
		}
		for (int i = 0; i < entityList.size(); i++) {
			if (entityList.get(i).getHandle() == handle){
				entityList.remove(i);
				break;
			}
		}
		for (int i = 0; i < enemyList.size(); i++) {
			if (enemyList.get(i).getHandle() == handle){
				enemyList.remove(i);
				break;
			}
		}
		for (int i = 0; i < bulletList.size(); i++) {
			if (bulletList.get(i).getHandle() == handle){
				bulletList.remove(i);
				break;
			}
		}
		for (int i = 0; i < crateList.size(); i++) {
			if (crateList.get(i).getHandle() == handle){
				crateList.remove(i);
				break;
			}
		}
		for (int i = 0; i < weaponList.size(); i++) {
			if (weaponList.get(i).getHandle() == handle){
				weaponList.remove(i);
				break;
			}
		}
	}
	
	//Resets all the lists and handle counter
	public void destroyAll(){
		playerEntity = null;
		entityList = new ArrayList<Entity>();
		enemyList = new ArrayList<EnemyEntity>();
		bulletList = new ArrayList<Bullet>();
		crateList = new ArrayList<Crate>();
		weaponList = new ArrayList<Weapon>();
		lastHandle = -1;
	}
}
